/* rc_demodulation_ftm.c */
/*======================================*/
/*=== Author: Elvis Chen             ===*/
/*=== eMail : 39343228@qq.com        ===*/
/*=== Date  : 2017/6/3               ===*/
/*======================================*/

#include "rc_demodulator_ftm.h"
#include "hal_ftm.h"

volatile bool SpeedDemodulatorIsSyncd = false, TurnDemodulatorIsSyncd = false;
volatile Capture_Stage_T SpeedCapStage, TurnCapStage;
volatile uint32_t SpeedPulseRiseCapVal, SpeedPulseFallCapVal, SpeedPulseWidth=PPM_ZERO_OFFSET_PULSE_WIDTH;
volatile uint32_t TurnPulseRiseCapVal, TurnPulseFallCapVal, TurnPulseWidth=PPM_ZERO_OFFSET_PULSE_WIDTH;
volatile int16_t SpeedPulseDiff=0, TurnPulseDiff=0;

void Demodulator_InitDevice(void)
{
    FTM_TimerConfig_T ftmTimerConfigStruct;

    /* 初始化FTM用于解调RC接收机PPM信号 */
    /* 时钟源频率为168MHz，计数频率约为21MHz，用于捕捉最大脉宽为2ms的PPM信号 */
    ftmTimerConfigStruct.SrcClkDivider = eFTM_SrcClkDiv_8;
    ftmTimerConfigStruct.ModuloValue = 0xFFFF;
    ftmTimerConfigStruct.InitValue = 0U;
    ftmTimerConfigStruct.TimerCountingMode = eFTM_TimerCountingUp;
    FTM_ConfigTimer(BSP_FTM_RC_CAPTURE_PORT, &ftmTimerConfigStruct);

    /* 系统复位后，首先使用上升沿捕捉模式，和RC接收机的PPM信号进行同步 */
    /* 同步完成后，切换为双边沿捕捉模式 */
    FTM_SetChannelMode(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM, eFTM_ChannelMode_InputCapture_OnRisingEdgeOnly);
    FTM_SetChannelMode(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_TURN_CAPTURE_CHANNEL_NUM, eFTM_ChannelMode_InputCapture_OnRisingEdgeOnly);
    
    /* 使能中断 */
    FTM_EnableChannelInterrupt(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM);
    FTM_EnableChannelInterrupt(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_TURN_CAPTURE_CHANNEL_NUM);
    
//    FTM_EnableChannelCounterReset(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM, true);
    
    NVIC_EnableIRQ(FTM3_IRQn);
   
    FTM_StartTimer(BSP_FTM_RC_CAPTURE_PORT, eFTM_ClkSrcAlt1);  /* System clock. */
}

void FTM3_IRQHandler()
{
    if(FTM_GetChannelFlag(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM) == true)
    {
        FTM_ClearChannelFlag(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM);
        if(SpeedDemodulatorIsSyncd == false)
        {
            SpeedDemodulatorIsSyncd = true;
            SpeedCapStage = CaptureOccuredAtRise;
            FTM_SetChannelMode(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM, eFTM_ChannelMode_InputCapture_OnEitherBothEdge);
        }
        
        if(SpeedCapStage == CaptureOccuredAtRise)
        {
            SpeedPulseRiseCapVal = FTM_GetChannelInputValue(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM);
            SpeedCapStage = CaptureOccuredAtFall;
        }
        else
        {
            SpeedPulseFallCapVal = FTM_GetChannelInputValue(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_SPEED_CAPTURE_CHANNEL_NUM);
            SpeedCapStage = CaptureOccuredAtRise;

            if(SpeedPulseFallCapVal < SpeedPulseRiseCapVal)
            {
                SpeedPulseWidth = 65535 - SpeedPulseRiseCapVal + SpeedPulseFallCapVal;
            }
            else
            {
                SpeedPulseWidth = SpeedPulseFallCapVal - SpeedPulseRiseCapVal;                
            }

            SpeedPulseDiff = SpeedPulseWidth - PPM_ZERO_OFFSET_PULSE_WIDTH;
        }        
    }

    if(FTM_GetChannelFlag(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_TURN_CAPTURE_CHANNEL_NUM) == true)
    {
        FTM_ClearChannelFlag(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_TURN_CAPTURE_CHANNEL_NUM);
        if(TurnDemodulatorIsSyncd == false)
        {
            TurnDemodulatorIsSyncd = true;
            TurnCapStage = CaptureOccuredAtRise;
            FTM_SetChannelMode(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_TURN_CAPTURE_CHANNEL_NUM, eFTM_ChannelMode_InputCapture_OnEitherBothEdge);
        }
        
        if(TurnCapStage == CaptureOccuredAtRise)
        {
            TurnPulseRiseCapVal = FTM_GetChannelInputValue(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_TURN_CAPTURE_CHANNEL_NUM);
            TurnCapStage = CaptureOccuredAtFall;
        }
        else
        {
            TurnPulseFallCapVal = FTM_GetChannelInputValue(BSP_FTM_RC_CAPTURE_PORT, BSP_GPIO_RC_TURN_CAPTURE_CHANNEL_NUM);
            TurnCapStage = CaptureOccuredAtRise;

            if(TurnPulseFallCapVal < TurnPulseRiseCapVal)
            {
                TurnPulseWidth = 65535 - TurnPulseRiseCapVal + TurnPulseFallCapVal;
            }
            else
            {
                TurnPulseWidth = TurnPulseFallCapVal - TurnPulseRiseCapVal;                
            }

            TurnPulseDiff = TurnPulseWidth - PPM_ZERO_OFFSET_PULSE_WIDTH;
        }        
    }
}    



/* EOF. */
